
/**
\file
Definition of the nmn::file_log_handler class.
\author Sean Tromans
*/

#ifndef NMN_LOG_HANDLERS_FILE_LOG_HANDLER_HPP
#define NMN_LOG_HANDLERS_FILE_LOG_HANDLER_HPP

#include <needs_more_ninja/template/log/logger.hpp>
#include <fstream>

namespace nmn
{

	/** Exception thrown when the provided output file for a logger cannot be opened. */
	class cannot_open_file : public std::exception
	{
	public:
		cannot_open_file( std::string const & file )
			:	std::exception( nmn::create_string( "nmn::cannot_open_file: %1%", file ).c_str( ) )
		{}
	};


	/**
	A log handler to output logging information to text a file.
	\author Sean Tromans
	*/
	template< typename char_t, typename traits_t = std::char_traits< char_t >, typename allocator_t = std::allocator< char_t > >
	class file_log_handler
	{
		//
		//	Public Member Types
		//
		public:

			typedef typename logger< char_t, traits_t, allocator_t > log_type;

		//
		//	Public Member Functions
		//
		public:

			/**
			Constructor
			@param filename The filename of the text file to output to.
			\author Sean Tromans
			*/
			file_log_handler( std::string const & filename )
				:	filename( filename )
			{
				std::ofstream file( filename.c_str( ), std::ios::out );
                if ( !file.is_open( ) )
                {
					throw cannot_open_file( filename );
                }

                file.close( );
			}

			/**
			Logger callback to output the formatted message to the debug console.
			@param message The unformatted raw message sent to the logger.
			@param formatted_message The formatted message created by the logger with additional information.
			\author Sean Tromans
			*/
			void operator( )( typename log_type::string_type const & /*message*/, typename log_type::string_type const & formatted_message )
			{
				write( formatted_message );
			}

		//
		//	Private Member Functions
		//
		private:

			/** Writes the provided string to the log file. */
			void write( typename log_type::string_type const & text )
			{
				std::basic_fstream< char_t, traits_t > file( filename.c_str( ), std::ios::app | std::ios::out );
				if ( file.is_open( ) )
				{
					file << text << std::endl;
				}
			}

		//
		//	Private Member Variables
		//
		private:

			std::string filename;
	};

}

#endif	//NMN_LOG_HANDLERS_CONSOLE_LOG_HANDLER_HPP
